package com.roger.uia.helper;

import android.os.SystemClock;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiScrollable;
import android.support.test.uiautomator.UiSelector;
import android.util.Log;

import com.roger.uia.helper.util.FileUtils;

import java.util.ArrayList;

import static com.roger.uia.helper.UiBase.mDevice;

public class UiDraw {
    private static final String TAG = "Test" + UiDraw.class.getSimpleName();
    public static UiObject rootObj = mDevice.findObject(new UiSelector().index(0));
    public ArrayList<String> txt = new ArrayList<>();

    public UiDraw(){
        Log.d(TAG,"run UiDraw");
    };

    public static UiDraw uiDraw() {
        return new UiDraw();
    }

    /**
     *   draw a obj and it's child layout
     *
     * @param obj
     * @param maxDepth
     * @return layout
     */
    public String drawObjLayout(UiObject obj, int maxDepth) {
        StringBuilder s = new StringBuilder();
        try {
            s.append("[");
            if(obj.exists()) {
                s.append(obj.getChildCount()).append(" ").append(obj.getClassName())
                        .append(" ").append(obj.isClickable()? "clickable" :"false") .append(" ")
                        .append(obj.isScrollable()? "scrollable":"false");
            }
            else return "[]";
            for(int i = 0 ;i < maxDepth;i++) {
                UiObject objC = obj.getChild(new UiSelector().instance(i));
                if (objC.exists()){
                    s.append(" && ").append(objC.getChildCount()).append(" ").append(objC.getClassName())
                            .append(" ").append(objC.isClickable()? "clickable" :"false") .append(" ")
                            .append(objC.isScrollable()? "scrollable":"false");
                }
                else break;
            }
        }catch (Throwable e){
            e.printStackTrace();
        }finally {
            s.append("]");
        }
        return s.toString();
    }

    public ArrayList<UiObject> needClickObj(UiObject obj, int maxDepth) {
        ArrayList<UiObject> objects = new ArrayList<>();
        String blackTxt = "(?i)OK|确定|Cancel|取消|Yes|是|No|否";
        String blackClass = "(?i).*Switch.*|.*EditText.*";
        String blackDesc = "(?i)back|返回|.*Search.*|.*搜索.*";
        try {
            for(int i = 0 ;i < maxDepth;i++) {
                UiObject objC = obj.getChild(new UiSelector().instance(i));
                if (objC.exists()) {
                    if (objC.isClickable() && !objC.getText().matches(blackTxt)
                            && !objC.getClassName().matches(blackClass) && !objC.getContentDescription().matches(blackDesc)
                            && !drawObjLayout(objC, 100).matches(blackClass))
                        objects.add(objC);
                } else break;
            }
        }catch (Throwable e){
            e.printStackTrace();
        }
        return objects;
    }

    public void handleObjClickable(UiObject root,String lastDraw){
        int i;
        try {
            String s = drawObjLayout(root,1000);
            ArrayList<UiObject> need = needClickObj(root,1000);
            if(need.size()>0){
                for(UiObject obj : need){
                    Log.d(TAG,"====2-click===="+obj.getClassName());
                    obj.clickAndWaitForNewWindow();
                    SystemClock.sleep(3000);
                    FileUtils.takeScreenPicTo("sdcard","2");
                    String ss = drawObjLayout(root,1000);
                    i=0;
                    while (!s.equals(ss) && i<5) {
                        mDevice.pressBack();
                        SystemClock.sleep(3000);
                        ss = drawObjLayout(root,1000);
                        i++;
                    }
                }
            }
        }catch (Throwable e){
            e.printStackTrace();
        }finally {
            i=0;
            while(!drawObjLayout(root,1000).equals(lastDraw) && i < 5){
                mDevice.pressBack();
                SystemClock.sleep(3000);
                i++;
            }
        }
    }


    public void handleObjClickable2(UiObject root){
        try {
            String rootObj = drawObjLayout(root,1000);
            ArrayList<UiObject> need = needClickObj(root,1000);
            FileUtils.takeScreenPicTo("sdcard","0");
            if(need.size()>0){
                for(UiObject obj : need){
                    Log.d(TAG,"====1-click===="+obj.getClassName());
                    obj.clickAndWaitForNewWindow();
                    SystemClock.sleep(3000);
                    String nowObj = drawObjLayout(root,1000);
                    if(!rootObj.equals(nowObj)) {
                        FileUtils.takeScreenPicTo("sdcard","1");
                        handleObjClickable(root,rootObj);
                    }
                }
            }
        } catch (Throwable e){
            e.printStackTrace();
        }
    }

    /**
     *  draw a obj and it's child txt
     * @param obj
     * @param maxDepth
     * @return all txt
     */
    public ArrayList<String> drawObjTxt(UiObject obj,int maxDepth){
        String currentScreen = drawObjLayout(obj,1000);
        UiObject objC,objS;
        int m;
        try{
            if(obj.exists()){
                //getText form obj
                if(!obj.getText().equals("")) txt.add(obj.getText());
                //get text from obj child
                for(int i = 0 ;i<maxDepth;i++){
                    objC = obj.getChild(new UiSelector().instance(i));
                    if(objC.exists()){
                        if(!objC.getText().equals("") && !txt.contains(objC.getText())) {
                            txt.add(objC.getText());
                        }
                    }else{
                        if(obj.isScrollable()){
                            new UiScrollable(new UiSelector().className(obj.getClassName())).scrollForward();
                            String newScreen =  drawObjLayout(obj,1000);
                            if(!newScreen.equals(currentScreen)) drawObjTxt(obj,maxDepth);
                            else break;
                        }
                        m = 0;
                        do{
                            objS = obj.getChild(new UiSelector().scrollable(true).instance(m++));
                            if(objS.exists()){
                                new UiScrollable(new UiSelector().className(objS.getClassName())).scrollForward();
                                String newScreen =  drawObjLayout(obj,1000);
                                if(!newScreen.equals(currentScreen)) drawObjTxt(obj,maxDepth);
                                else break;
                            }
                        } while (objS.exists());
                        break;
                    }
                }
            }
        }catch (Throwable e){
            e.printStackTrace();
        }
        return txt;
    }

    public void scrollObjBeginning(UiObject obj){
        UiObject objS;
        int m;
        try{
            if(obj.exists()){
                if(obj.isScrollable())
                    new UiScrollable(new UiSelector().className(obj.getClassName())).scrollToBeginning(5000);
                m = 0;
                do{
                   objS = obj.getChild(new UiSelector().scrollable(true).instance(m++));
                    if(objS.exists()){
                        new UiScrollable(new UiSelector().className(objS.getClassName())).scrollToBeginning(5000);
                    }
                } while (objS.exists());
            }else{
                m = 0;
                do{
                    objS = rootObj.getChild(new UiSelector().scrollable(true).instance(m++));
                    if(objS.exists()){
                        new UiScrollable(new UiSelector().className(objS.getClassName())).scrollIntoView(obj);
                        if(obj.exists()){
                            scrollObjBeginning(obj);
                            break;
                        }
                    }
                } while (objS.exists());
            }
        }catch (Throwable e){
            e.printStackTrace();
        }
    }


}
